package com.dz.risk.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dz.risk.common.ExcelUtils;
import com.dz.risk.dao.TemporaryTableOfDataDao;
import com.dz.risk.pojo.domain.ReportCodeLocatingTemplateEntity;
import com.dz.risk.pojo.domain.TemporaryTableOfDataEntity;
import com.dz.risk.pojo.model.PageModel;
import com.dz.risk.service.ReportCodeLocatingTemplateService;
import com.dz.risk.service.TemporaryTableOfDataService;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


@Service("temporaryTableOfDataService")
public class TemporaryTableOfDataServiceImpl extends ServiceImpl<TemporaryTableOfDataDao, TemporaryTableOfDataEntity> implements TemporaryTableOfDataService {


    private final TemporaryTableOfDataDao temporaryTableOfDataDao;

    private final ReportCodeLocatingTemplateService reportCodeLocatingTemplateService;

    @Autowired
    public TemporaryTableOfDataServiceImpl(TemporaryTableOfDataDao temporaryTableOfDataDao, ReportCodeLocatingTemplateService reportCodeLocatingTemplateService) {
        this.temporaryTableOfDataDao = temporaryTableOfDataDao;
        this.reportCodeLocatingTemplateService = reportCodeLocatingTemplateService;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(TemporaryTableOfDataEntity temporaryTableOfDataEntity) {
        temporaryTableOfDataDao.insert(temporaryTableOfDataEntity);
    }

    @Override
    public IPage<TemporaryTableOfDataEntity> query(PageModel pageModel, TemporaryTableOfDataEntity temporaryTableOfDataEntity) {
        IPage<TemporaryTableOfDataEntity> page = new Page<>();
        page.setCurrent(pageModel.getPageNum());
        page.setSize(pageModel.getPageSize());
        QueryWrapper<TemporaryTableOfDataEntity> wrapper = new QueryWrapper<TemporaryTableOfDataEntity>();

        wrapper.lambda()
                .like(!StringUtils.isEmpty(temporaryTableOfDataEntity.getIndexId()), TemporaryTableOfDataEntity::getIndexId, temporaryTableOfDataEntity.getIndexId())
                .eq(!StringUtils.isEmpty(temporaryTableOfDataEntity.getDate()), TemporaryTableOfDataEntity::getDate, temporaryTableOfDataEntity.getDate())
                .orderByDesc(TemporaryTableOfDataEntity::getCreateTime);


        IPage<TemporaryTableOfDataEntity> temporaryTableOfDataEntityIPage = temporaryTableOfDataDao.selectPage(page, wrapper);
        return temporaryTableOfDataEntityIPage;
    }

    /**
     * 根据指标ID跟版本号查询数据
     *
     * @param indexId 指标ID
     * @param date    版本号
     * @return 指标集合
     */
    @Override
    public List<TemporaryTableOfDataEntity> selectByIndexIdAndDate(String indexId, Long date) {
        QueryWrapper<TemporaryTableOfDataEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(TemporaryTableOfDataEntity::getIndexId, indexId)
                .eq(TemporaryTableOfDataEntity::getDate, date)
                .orderByDesc(TemporaryTableOfDataEntity::getCreateTime);
        return temporaryTableOfDataDao.selectList(wrapper);
    }

    @Override
    public List<TemporaryTableOfDataEntity> selectByParams() {
        QueryWrapper<TemporaryTableOfDataEntity> wrapper = new QueryWrapper<>();
        return temporaryTableOfDataDao.selectList(wrapper);
    }

    /**
     * 编码位置模板导入
     *
     * @param file 文件流
     * @throws IOException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importOfDataCodingTemplateForDemandForm(MultipartFile file) throws IOException {
        Assert.notNull(file, "文件不能为空");
        final String numberPrefix = "M{";
        final String numberSuffix = "}";
        //需要记录编码位置得数据集合
        List<ReportCodeLocatingTemplateEntity> reportCodeLocatingTemplateEntities = new ArrayList<>();

        Workbook workbook = ExcelUtils.getWorkbook(file.getInputStream(), file.getOriginalFilename());

        //获取第一个sheet表
        Sheet sheet = workbook.getSheetAt(0);
        //获取起始行
        int lastRowNum = sheet.getLastRowNum();
        //遍历数据行
        for (int rowNum = 0; rowNum <= lastRowNum; rowNum++) {
            //获取当前遍历行
            Row row = sheet.getRow(rowNum);
            if (Objects.nonNull(row)) {
                //获取当前行的数据起始列
                short firstCellNum = row.getFirstCellNum();
                short lastCellNum = row.getLastCellNum();

                if (firstCellNum != lastCellNum) {
                    //遍历当前行的所有列
                    for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
                        //获取当前遍历的单元格
                        Cell cell = row.getCell(cellNum);
                        String stringCellValue = String.valueOf(ExcelUtils.getCellValue(cell));

                        if (!StringUtils.isEmpty(stringCellValue) && stringCellValue.contains(numberPrefix)) {
                            //去除编码前后缀得到纯编码
                            stringCellValue = stringCellValue.replace(numberPrefix, "").replace(numberSuffix, "").trim();
                            reportCodeLocatingTemplateEntities.add(ReportCodeLocatingTemplateEntity
                                    .builder()
                                    .indexId(stringCellValue)
                                    .columnNumber(cellNum)
                                    .lineNumber(rowNum)
                                    .build());
                        }
                    }
                }
            }
        }
        //先删除模板编码数据
        reportCodeLocatingTemplateService.remove(new UpdateWrapper<>());
        //新增新增编码模板数据
        reportCodeLocatingTemplateService.saveBatch(reportCodeLocatingTemplateEntities);
    }

    /**
     * 导入模板编码的实际数据
     *
     * @param file 文件流
     * @param date 数据版本
     */
    @Override
    public void importTheActualDataOfTheTemplateEncoding(MultipartFile file, Long date) throws IOException {
        Assert.notNull(file, "文件不能为空");
        //需要记录编码位置得数据集合
        List<TemporaryTableOfDataEntity> temporaryTableOfDataEntities = new ArrayList<>();

        Workbook workbook = ExcelUtils.getWorkbook(file.getInputStream(), file.getOriginalFilename());

        //获取第一个sheet表
        Sheet sheet = workbook.getSheetAt(0);
        //获取起始行
        int lastRowNum = sheet.getLastRowNum();
        //遍历数据行
        for (int rowNum = 0; rowNum <= lastRowNum; rowNum++) {
            //获取当前遍历行
            Row row = sheet.getRow(rowNum);
            if (Objects.nonNull(row)) {
                //获取当前行的数据起始列
                short firstCellNum = row.getFirstCellNum();
                short lastCellNum = row.getLastCellNum();

                if (firstCellNum != lastCellNum) {
                    //遍历当前行的所有列
                    for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
                        //获取当前遍历的单元格
                        Cell cell = row.getCell(cellNum);
                        String stringCellValue = String.valueOf(ExcelUtils.getCellValue(cell));

                        //如果单元格有值
                        if (!StringUtils.isEmpty(stringCellValue)) {
                            //根据行号列号查询编码
                            List<String> indexIds = reportCodeLocatingTemplateService.selectIndexIdByLineNumberAndColumnNumber(rowNum, cellNum);

                            if (!CollectionUtils.isEmpty(indexIds)) {
                                temporaryTableOfDataEntities.add(TemporaryTableOfDataEntity
                                        .builder()
                                        .date(date)
                                        .indexId(indexIds.get(0))
                                        .indexValue(stringCellValue)
                                        .build());
                            }
                        }
                    }
                }
            }
        }
        //新增数据
        this.saveBatch(temporaryTableOfDataEntities);
    }

}